/*
 * Nombre: DAOAsignaturaOfertaAcademica.java
 * Version: 1.1.0
 * Diagrama: GAPI v1.5.2
 * Autor: Luis Jorge Uicab Azcorra
 * Creado: 24-feb-2013
 * Modificado: 13-abr-2013
 */

package DAO;

import AccesoBD.AccesoBaseDatos;
import Dominio.Asignatura;
import Dominio.AsignaturaOfertaAcademica;
import Dominio.FragmentoHorario;
import Dominio.Profesor;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

/**
 * @author Luis J
 * Description: Clase que se encarga de realizar la conexion y la
 * administracion con la tabla de asiganturas de la Oferta Academica
 * dentro de la base de datos.
 * Date: 24/02/2013
 */
public class DAOAsignaturaOfertaAcademica {
    private static final String TABLA_ASIGNATURA_O_A = "asignaturasOferta";
    private static final String COLUMNA_CLAVE_ASIGNATURA_OFERTA = "claveAsignaturaOferta";
    private static final String COLUMNA_CLAVE_ASIGNATURA = "cveAsignatura";
    private static final String COLUMNA_CLAVE_PROFESOR = "claveProfesor";
    private static final String COLUMNA_NOMBRE = "nombre";
    private static final String COLUMNA_PROGRAMA_EDUCATIVO = "programaEducativo";
    private static final String COLUMNA_SEMESTRE = "semestre";
    private AccesoBaseDatos acceso = new AccesoBaseDatos();
    private Connection conexion = null;

    /**
     * Constructor de la clase, abre la conexion con la base de datos
     */
    public DAOAsignaturaOfertaAcademica() {
        this.conexion = acceso.abrirConexion();
    }
    
    /**
     * Cierra la conexion con la Base de Datos
     */
    public void cerrarConexionAAsignaturaOferta() {
        acceso.cerrarConexion(conexion);
    }
    
    /**
     * Metodo que se encarga de buscar una asignatura de tipo
     * AsignaturaOfertaAcademica dentro de la base de datos utilizando como
     * referencia la clave de la asignatura de la oferta.
     * @param claveAsignaturaOfertaAcademica La Clave de la Asignatura
     * @return La Asignatura
     */
    public AsignaturaOfertaAcademica buscarAsignaturaOfertaAcademica(int claveAsignaturaOfertaAcademica){
        String queryBusqueda = "SELECT * FROM "+TABLA_ASIGNATURA_O_A+ " WHERE " + COLUMNA_CLAVE_ASIGNATURA_OFERTA + " = " + claveAsignaturaOfertaAcademica;
        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            ResultSet resultado = sentencia.executeQuery(queryBusqueda);
            resultado.first();
            if(resultado.getRow() != 0){
                AsignaturaOfertaAcademica asignatura = new AsignaturaOfertaAcademica();
                asignatura.setClaveAsignaturaOferta(resultado.getInt(1));
                asignatura.setClaveAsignatura(resultado.getInt(2));
                DAOProfesor daoP = new DAOProfesor();
                Profesor profesor = daoP.buscarProfesor(resultado.getInt(3));
                asignatura.setMaestro(profesor);
                asignatura.setNombre(resultado.getString(4));
                asignatura.setProgramaEducativo(resultado.getString(5));
                asignatura.setSemestre(resultado.getString(6));
                DAOHorario daoH = new DAOHorario();
                ArrayList<FragmentoHorario> horario = daoH.buscarTodosLosHorarios(resultado.getInt(1));
                asignatura.setHorario(horario);
                return asignatura;
            } else {
                return null;
            }
        } catch (SQLException ex) {
            System.err.println("Problemas de SQL:\n"+ex.toString());
            return null;
        }
    }
    
    /**
     * Metodo que se encarga de buscar todas las asignaturas de tipo
     * AsignaturaOfertaAcademica dentro de la base de datos.
     * @return Las Asignaturas
     */
    public ArrayList<AsignaturaOfertaAcademica> buscarAsignaturasDeOfertaAcademica(){
        String queryBusqueda = "SELECT * FROM "+TABLA_ASIGNATURA_O_A;
        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            ResultSet resultado = sentencia.executeQuery(queryBusqueda);
            ArrayList<AsignaturaOfertaAcademica> asignaturas = new ArrayList<>();
            while(resultado.next()){
                AsignaturaOfertaAcademica asignatura = new AsignaturaOfertaAcademica();
                asignatura.setClaveAsignaturaOferta(resultado.getInt(1));
                asignatura.setClaveAsignatura(resultado.getInt(2));
                DAOProfesor daoP = new DAOProfesor();
                Profesor profesor = daoP.buscarProfesor(resultado.getInt(3));
                asignatura.setMaestro(profesor);
                asignatura.setNombre(resultado.getString(4));
                asignatura.setProgramaEducativo(resultado.getString(5));
                asignatura.setSemestre(resultado.getString(6));
                DAOHorario daoH = new DAOHorario();
                ArrayList<FragmentoHorario> horario = daoH.buscarTodosLosHorarios(resultado.getInt(1));
                asignatura.setHorario(horario);
                asignaturas.add(asignatura);
            }
            return asignaturas;
        } catch (SQLException ex) {
            System.err.println("Problemas de SQL:\n"+ex.toString());
            return new ArrayList<>();
        }
    }
    
    /**
     * Metodo que se encarga de buscar la clave de una Asignatura de la oferta
     * academica a partir de una Asignatura de la oferta Académica. El metodo
     * utiliza los parametros Clave asignatura, Clave profesor, Nombre, Programa
     * Educativo y Semestre.
     * @param asignatura La Asigantura de la Oferta
     * @return La clave
     */
    public int buscarClaveAsignaturaOfertaAcademica(AsignaturaOfertaAcademica asignatura){
        String queryBusqueda = "SELECT "+COLUMNA_CLAVE_ASIGNATURA_OFERTA+" FROM "+TABLA_ASIGNATURA_O_A
                + " WHERE " + COLUMNA_CLAVE_ASIGNATURA + " = " + asignatura.getClaveAsignatura() +" AND "
                + COLUMNA_CLAVE_PROFESOR + " = " + asignatura.getMaestro().getClaveProfesor() +" AND "
                + COLUMNA_NOMBRE + " = '" + asignatura.getNombre() +"' AND "
                + COLUMNA_PROGRAMA_EDUCATIVO + " = '" + asignatura.getProgramaEducativo() +"' AND "
                + COLUMNA_SEMESTRE + " = '" + asignatura.getSemestre() +"'";
        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            ResultSet resultado = sentencia.executeQuery(queryBusqueda);
            resultado.first();
            if(resultado.getRow() != 0){
                return resultado.getInt(1);
            } else {
                return -1;
            }
        } catch (SQLException ex) {
            System.err.println("Problemas de SQL:\n"+ex.toString());
            return -1;
        }
    }
    
    /**
     * Metodo que se encarga del registro de Una asignatura de tipo
     * AsignaturaOfertaAcademica dentro de la Base de Datos
     * @param asignatura La asignatura de la Oferta Academica
     */
    public void registrarAsignatura(AsignaturaOfertaAcademica asignatura){
        try {
            int idAsignatura=asignatura.getClaveAsignatura();
            String programaEducativo=asignatura.getProgramaEducativo();
            String semestre=asignatura.getSemestre();
            int idProfesor=asignatura.getMaestro().getClaveProfesor();
            
            DAOAsignatura daoA = new DAOAsignatura();
            String nombreAsignatura = daoA.buscarAsignatura(idAsignatura).getNombre();
            
            
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String queryInsertar = "INSERT INTO " + TABLA_ASIGNATURA_O_A + " ("
                    + COLUMNA_CLAVE_ASIGNATURA +","
                    + COLUMNA_CLAVE_PROFESOR +","
                    + COLUMNA_NOMBRE+","
                    + COLUMNA_PROGRAMA_EDUCATIVO +","
                    + COLUMNA_SEMESTRE
                    + ") VALUES ("
                    +idAsignatura+","
                    +idProfesor+",'"
                    +nombreAsignatura+"','"
                    +programaEducativo+"','"
                    +semestre+"');";
             sentencia.executeUpdate(queryInsertar, Statement.RETURN_GENERATED_KEYS);
            
            int clave = -1;
            ResultSet resultSet = sentencia.getGeneratedKeys();

            if (resultSet.next()) {
                clave = resultSet.getInt(1);
            }
             
             
            DAOHorario daoH = new DAOHorario();
            ArrayList<FragmentoHorario> horarios = asignatura.getHorario();
            for(int index=0;index<horarios.size();index++){
                daoH.registrarHorario(clave, horarios.get(index));
            }
            daoH.cerrarConexionAHorario();
            daoA.cerrarConexionAAsignatura();
        } catch (SQLException ex) {
            System.out.println("Ocurrió un problema al tratar de registrar la Asignatura");
        }
    }
    
    /**
     * Metodo que se encarga de eliminar una Asignatura de Tipo Asignatura de
     * Oferta Academica dentro de la Base de Datos
     * @param claveAsignatura La Clave de la Asignatura de Oferta Academica
     */
    public void eliminarAsignatura(int claveAsignatura) {
        try {
            DAOHorario daoH = new DAOHorario();
            daoH.eliminarHorarioPorAsignatura(claveAsignatura);
            daoH.cerrarConexionAHorario();
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String deleteQuery = "DELETE FROM " + TABLA_ASIGNATURA_O_A + " WHERE " + COLUMNA_CLAVE_ASIGNATURA_OFERTA + " = '" + claveAsignatura + "'";
            sentencia.executeUpdate(deleteQuery);
        } catch (SQLException ex) {
            System.out.println("Ocurrió un problema al tratar de eliminar una Asignatura de Oferta Academica");
        }
    }

    /**
     * Metodo que se encarga de actualizar una asignatura de la Oferta Academica.
     * @param claveAsignaturaOferta La Clave de la Asignatura de la Oferta
     * @param asignatura La Asignatura de la Oferta Modificada
     */
    public void actualizarAsignatura(int claveAsignaturaOferta, AsignaturaOfertaAcademica asignatura) {
        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String queryUpdate = "UPDATE " + TABLA_ASIGNATURA_O_A + " SET "
                    + COLUMNA_CLAVE_ASIGNATURA_OFERTA + " = '" + asignatura.getClaveAsignaturaOferta() + "' ,"
                    + COLUMNA_CLAVE_ASIGNATURA + " = '" + asignatura.getClaveAsignatura() +"' ,"
                    + COLUMNA_CLAVE_PROFESOR + " = '" + asignatura.getMaestro().getClaveProfesor() +"' ,"
                    + COLUMNA_NOMBRE + " = '" + asignatura.getNombre() +"' ,"
                    + COLUMNA_PROGRAMA_EDUCATIVO + " = '" + asignatura.getProgramaEducativo() +"' ,"
                    + COLUMNA_SEMESTRE + " = '" + asignatura.getSemestre() +"' "
                    + " WHERE " + COLUMNA_CLAVE_ASIGNATURA_OFERTA+ " = '" + claveAsignaturaOferta + "'"
                    + ";";
            sentencia.executeUpdate(queryUpdate);
            DAOHorario daoH = new DAOHorario();
            daoH.eliminarHorarioPorAsignatura(asignatura.getClaveAsignaturaOferta());
            for(int index=0; index<asignatura.getHorario().size(); index++){
                daoH.registrarHorario(asignatura.getClaveAsignaturaOferta(), asignatura.getHorario().get(index));
            }
            daoH.cerrarConexionAHorario();
        } catch (SQLException ex) {
            System.out.println("Ocurrió un problema al tratar de actualizar los datos de una Asignatura de Oferta Academica");
        }
    }
    
    /**
     * Metodo que se encarga de buscar una asignatura dentro de la base de datos
     * utilizando como referencia la clave de la asignatura de la oferta.
     * @param claveAsignaturaOferta La clave de la Asignatura
     * @return La Asignatura
     */
    public Asignatura obtenerAsignaturaDeOferta(int claveAsignaturaOferta){
        String query = "SELECT * FROM "+TABLA_ASIGNATURA_O_A+" WHERE "+COLUMNA_CLAVE_ASIGNATURA_OFERTA+"='"+claveAsignaturaOferta+"';";
        try{
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            ResultSet resultado = sentencia.executeQuery(query);
            Asignatura asignatura = null;
            DAOAsignatura daoAsignatura = new DAOAsignatura();
            resultado.first();
            if(resultado.getRow() != 0){
                int claveAsignatura = resultado.getInt(2);//el 2 es la columna de Asignatura
                asignatura = daoAsignatura.buscarAsignatura(claveAsignatura);
            }
            daoAsignatura.cerrarConexionAAsignatura();
            return asignatura;
        }catch (SQLException ex){
            System.err.println("Problemas de SQL:\n"+ex.toString());
        }
        return null;
    }
    
    /**
     * Metodo que se encarga de eliminar todas las Asignatura de Tipo Asignatura
     * de Oferta Academica dentro de la Base de Datos.
     */
    public void eliminarAsignaturasOfertaAcademica(){
          try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String queryDelete = "DELETE FROM " + TABLA_ASIGNATURA_O_A ;
            sentencia.executeUpdate(queryDelete);
        } catch (SQLException ex) {
            System.out.println("Ocurrió un problema al tratar de actualizar los datos de una Asignatura de Oferta Academica");
        }
    }
    
    /**
     * Metodo que se encarga de buscar Asignaturas que se encuentran ofertadas
     * y que corresponden a cierto programa educativo.
     * @param abreviaturaPE El Programa educativo
     * @return Las asignaturas encontradas
     */
    public ArrayList<AsignaturaOfertaAcademica> buscarAsignaturasOfertadasPorPE(String abreviaturaPE) {

        ArrayList<AsignaturaOfertaAcademica> listaAsignaturasOfertadas = new ArrayList<AsignaturaOfertaAcademica>();

        String query = "SELECT * FROM " + TABLA_ASIGNATURA_O_A + " WHERE " + COLUMNA_PROGRAMA_EDUCATIVO + " = '" + abreviaturaPE + "';";

        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            ResultSet resultado = sentencia.executeQuery(query);

            DAOAsignatura daoAsignatura = new DAOAsignatura();

            while (resultado.next()) {
                AsignaturaOfertaAcademica asignaturaOfertaAcademica = new AsignaturaOfertaAcademica();
                asignaturaOfertaAcademica.setClaveAsignaturaOferta(resultado.getInt(1));
                asignaturaOfertaAcademica.setClaveAsignatura(resultado.getInt(2));

                DAOProfesor daoP = new DAOProfesor();
                Profesor profesor = daoP.buscarProfesor(resultado.getInt(3));
                asignaturaOfertaAcademica.setMaestro(profesor);
                asignaturaOfertaAcademica.setNombre(resultado.getString(4));
                asignaturaOfertaAcademica.setProgramaEducativo(resultado.getString(5));
                asignaturaOfertaAcademica.setSemestre(resultado.getString(6));

                DAOHorario daoH = new DAOHorario();
                ArrayList<FragmentoHorario> horario = daoH.buscarTodosLosHorarios(resultado.getInt(1));
                asignaturaOfertaAcademica.setHorario(horario);

                listaAsignaturasOfertadas.add(asignaturaOfertaAcademica);

            }

            daoAsignatura.cerrarConexionAAsignatura();

        } catch (SQLException ex) {
            System.err.println("Problemas de SQL:\n" + ex.toString());
        }
        return listaAsignaturasOfertadas;
    }
    
    /**
     * Metodo que se encarga de buscar Asignaturas que se encuentran ofertadas, 
     * que corresponden a cierto programa educativo y que correspondan al turno
     * Matutino.
     * @param abreviaturaPE El Programa educativo
     * @return Las asignaturas encontradas
     */
    public ArrayList<AsignaturaOfertaAcademica> buscarAsignaturasOfertadasPorPEMatutino(String abreviaturaPE) {

        ArrayList<AsignaturaOfertaAcademica> listaAsignaturasOfertadas = new ArrayList<AsignaturaOfertaAcademica>();

        String query = "SELECT * FROM " + TABLA_ASIGNATURA_O_A + " WHERE " + COLUMNA_PROGRAMA_EDUCATIVO + " = '" + abreviaturaPE + "';";

        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            ResultSet resultado = sentencia.executeQuery(query);

            DAOAsignatura daoAsignatura = new DAOAsignatura();

            while (resultado.next()) {
                AsignaturaOfertaAcademica asignaturaOfertaAcademica = new AsignaturaOfertaAcademica();
                asignaturaOfertaAcademica.setClaveAsignaturaOferta(resultado.getInt(1));
                asignaturaOfertaAcademica.setClaveAsignatura(resultado.getInt(2));

                DAOProfesor daoP = new DAOProfesor();
                Profesor profesor = daoP.buscarProfesor(resultado.getInt(3));
                asignaturaOfertaAcademica.setMaestro(profesor);
                asignaturaOfertaAcademica.setNombre(resultado.getString(4));
                asignaturaOfertaAcademica.setProgramaEducativo(resultado.getString(5));
                asignaturaOfertaAcademica.setSemestre(resultado.getString(6));

                DAOHorario daoH = new DAOHorario();
                ArrayList<FragmentoHorario> horario = daoH.buscarTodosLosHorarios(resultado.getInt(1));
                asignaturaOfertaAcademica.setHorario(horario);
                boolean agregar = false;
                boolean continuar = true;
                for(int i=0;i<horario.size() && continuar;i++){
                    if(horario.get(i).getHoraFin().compareTo("15:00:00")<=0){
                        agregar=true;
                    }else{
                        continuar = false;
                        agregar = false;
                    }
                }
                if(agregar){
                    listaAsignaturasOfertadas.add(asignaturaOfertaAcademica);
                }

            }
            
            daoAsignatura.cerrarConexionAAsignatura();

        } catch (SQLException ex) {
            System.err.println("Problemas de SQL:\n" + ex.toString());
        }
        return listaAsignaturasOfertadas;
    }
    
    /**
     * Metodo que se encarga de buscar Asignaturas que se encuentran ofertadas, 
     * que corresponden a cierto programa educativo y que correspondan al turno
     * Vespertino.
     * @param abreviaturaPE El Programa educativo
     * @return Las asignaturas encontradas
     */
    public ArrayList<AsignaturaOfertaAcademica> buscarAsignaturasOfertadasPorPEVeespertino(String abreviaturaPE) {

        ArrayList<AsignaturaOfertaAcademica> listaAsignaturasOfertadas = new ArrayList<AsignaturaOfertaAcademica>();

        String query = "SELECT * FROM " + TABLA_ASIGNATURA_O_A + " WHERE " + COLUMNA_PROGRAMA_EDUCATIVO + " = '" + abreviaturaPE + "';";

        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            ResultSet resultado = sentencia.executeQuery(query);

            DAOAsignatura daoAsignatura = new DAOAsignatura();

            while (resultado.next()) {
                AsignaturaOfertaAcademica asignaturaOfertaAcademica = new AsignaturaOfertaAcademica();
                asignaturaOfertaAcademica.setClaveAsignaturaOferta(resultado.getInt(1));
                asignaturaOfertaAcademica.setClaveAsignatura(resultado.getInt(2));

                DAOProfesor daoP = new DAOProfesor();
                Profesor profesor = daoP.buscarProfesor(resultado.getInt(3));
                asignaturaOfertaAcademica.setMaestro(profesor);
                asignaturaOfertaAcademica.setNombre(resultado.getString(4));
                asignaturaOfertaAcademica.setProgramaEducativo(resultado.getString(5));
                asignaturaOfertaAcademica.setSemestre(resultado.getString(6));

                DAOHorario daoH = new DAOHorario();
                ArrayList<FragmentoHorario> horario = daoH.buscarTodosLosHorarios(resultado.getInt(1));
                asignaturaOfertaAcademica.setHorario(horario);
                boolean agregar = false;
                boolean continuar = true;
                for(int i=0;i<horario.size() && continuar;i++){
                    if(horario.get(i).getHoraInicio().compareTo("15:00:00")>=0){
                        agregar=true;
                    }else{
                        continuar = false;
                        agregar = false;
                    }
                }
                if(agregar){
                    listaAsignaturasOfertadas.add(asignaturaOfertaAcademica);
                }

            }
            
            daoAsignatura.cerrarConexionAAsignatura();

        } catch (SQLException ex) {
            System.err.println("Problemas de SQL:\n" + ex.toString());
        }
        return listaAsignaturasOfertadas;
    }
    
    /**
     * Metodo que se encarga de verificar la existencia de asignaturas dentro de
     * un programa educativo.
     * @param claveProgramaEducativoEnCadena El programa educativo
     * @return Un booleano que indica la existencia
     */
    public boolean existeAsignaturasDeOferta(String claveProgramaEducativoEnCadena) {
        boolean existe = false;
        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String query = "SELECT * FROM " + TABLA_ASIGNATURA_O_A + " WHERE " + COLUMNA_PROGRAMA_EDUCATIVO
                    + " ='" + claveProgramaEducativoEnCadena + "'";
            ResultSet resultado = sentencia.executeQuery(query);
            if (resultado.first()) {
                existe = true;
            }
        } catch (SQLException ex) {
            System.out.println("Ocurrió un problema al intentar recuperar la asignatura como requerimiento académico.\n");
        }
        return existe;
    }
    
    /**
     * Metodo que se encarga de verificar la existencia de profesores dentro de
     * alguna de las asignaturas ofertadas.
     * @param claveProfesor  La clave del profesor
     * @return Un booleano que indica la existencia
     */
    public boolean existeProfesorEnAsignaturasOfertadas(int claveProfesor) {
        boolean existe = false;
        try {
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String query = "SELECT * FROM " + TABLA_ASIGNATURA_O_A + " WHERE " + COLUMNA_CLAVE_PROFESOR
                    + " ='" + claveProfesor + "'";
            ResultSet resultado = sentencia.executeQuery(query);
            
            while (resultado.next()) {
                existe = true;
            }
        } catch (SQLException ex) {
            System.out.println("Ocurrió un problema al intentar recuperar la asignatura como requerimiento académico.\n");
        }
        return existe;
    }
}
